package top.lixunda.ecommerce.server.good.api.entity.dto;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.api.condition.ILambdaQueryWrapperDTO;
import top.lixunda.ecommerce.server.good.api.entity.db.GoodsDO;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 店铺端查询条件DTO
 * 条件查询商品数据信息，包括分页
 *
 * @author Xumda
 * @version time:2019/12/17 14:01
 */
@Slf4j
@ApiModel(value = "店铺端查询条件DTO", description = "条件查询商品数据信息，包括分页")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class GoodsStoreQueryDTO implements ILambdaQueryWrapperDTO<GoodsDO> {

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String FILTER_COLUMN_GOOD_CATEGORY = "category";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String FILTER_COLUMN_GROUP_NAME = "group";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String FILTER_COLUMN_SELL_POINT = "sellPoint";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String FILTER_COLUMN_STATE = "state";


    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_NAME = "name";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_CATEGORY = "goodCategoryName";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_GROUP = "groupName";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_SELL_POINT = "sellPoint";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_FREIGHT = "freight";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_CREATE_TIME = "createTime";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_STATE = "state";

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static final String SORT_COLUMN_REMARK = "remark";

    /**
     * 搜索字符串
     */
    @ApiModelProperty("搜索字符串")
    private String search;

    /**
     * 筛选条件，键为数据库字段，值为筛选数据
     */
    @ApiModelProperty(value = "筛选条件", notes = "键为数据库字段，值为筛选数据")
    private Map<String, List<String>> filter;

    /**
     * 排序条件，有顺序
     */
    @ApiModelProperty("排序条件")
    private List<SortEntity> sort;

    /**
     * 处理筛选条件啊
     *
     * @param wrapper LambdaQueryWrapper
     */
    private void dealWithFilter(LambdaQueryWrapper<GoodsDO> wrapper) {
        // 筛选条件
        if (ObjectValidators.isNotEmpty(filter)) {
            Consumer<LambdaQueryWrapper<GoodsDO>> consumer = innerWrapper -> {
                for (Map.Entry<String, List<String>> entry : filter.entrySet()) {
                    List<String> values = entry.getValue();
                    if (ObjectValidators.isEmpty(values)) {
                        continue;
                    }
                    values.forEach(val -> {
                        switch (entry.getKey()) {
                            case FILTER_COLUMN_GOOD_CATEGORY:
                                innerWrapper.or().eq(GoodsDO::getGoodCategoryId, val);
                                break;
                            case FILTER_COLUMN_GROUP_NAME:
                                innerWrapper.or().eq(GoodsDO::getGroupId, val);
                                break;
                            case FILTER_COLUMN_SELL_POINT:
                                innerWrapper.or().eq(GoodsDO::getSellPoint, val);
                                break;
                            case FILTER_COLUMN_STATE:
                                innerWrapper.or().eq(GoodsDO::getState, val);
                                break;
                            default:
                                log.error("错误的筛选条件");
                                break;
                        }
                    });
                }
            };
            wrapper.and(consumer);
        }
    }

    /**
     * 处理排序条件
     *
     * @param wrapper LambdaQueryWrapper
     */
    private void dealWithOrderBy(LambdaQueryWrapper<GoodsDO> wrapper) {
        // 排序条件
        if (ObjectValidators.isNotEmpty(sort)) {
            this.sort.forEach(item -> {
                // 倒序，else后是顺序，即默认顺序
                if (SortEntity.SORT_DESC.equals(item.getOrder().toUpperCase())) {
                    switch (item.getColumn()) {
                        case SORT_COLUMN_NAME:
                            wrapper.orderByDesc(GoodsDO::getName);
                            break;
                        case SORT_COLUMN_CATEGORY:
                            wrapper.orderByDesc(GoodsDO::getGoodCategoryName);
                            break;
                        case SORT_COLUMN_GROUP:
                            wrapper.orderByDesc(GoodsDO::getGroupName);
                            break;
                        case SORT_COLUMN_SELL_POINT:
                            wrapper.orderByDesc(GoodsDO::getSellPoint);
                            break;
                        case SORT_COLUMN_FREIGHT:
                            wrapper.orderByDesc(GoodsDO::getFreight);
                            break;
                        case SORT_COLUMN_CREATE_TIME:
                            wrapper.orderByDesc(GoodsDO::getCreateTime);
                            break;
                        case SORT_COLUMN_REMARK:
                            wrapper.orderByDesc(GoodsDO::getRemark);
                            break;
                        case SORT_COLUMN_STATE:
                            wrapper.orderByDesc(GoodsDO::getState);
                            break;
                        default:
                            log.debug("不支持的排序字段");
                            break;
                    }
                } else {
                    switch (item.getColumn()) {
                        case SORT_COLUMN_NAME:
                            wrapper.orderByAsc(GoodsDO::getName);
                            break;
                        case SORT_COLUMN_CATEGORY:
                            wrapper.orderByAsc(GoodsDO::getGoodCategoryName);
                            break;
                        case SORT_COLUMN_GROUP:
                            wrapper.orderByAsc(GoodsDO::getGroupName);
                            break;
                        case SORT_COLUMN_SELL_POINT:
                            wrapper.orderByAsc(GoodsDO::getSellPoint);
                            break;
                        case SORT_COLUMN_FREIGHT:
                            wrapper.orderByAsc(GoodsDO::getFreight);
                            break;
                        case SORT_COLUMN_CREATE_TIME:
                            wrapper.orderByAsc(GoodsDO::getCreateTime);
                            break;
                        case SORT_COLUMN_REMARK:
                            wrapper.orderByAsc(GoodsDO::getRemark);
                            break;
                        case SORT_COLUMN_STATE:
                            wrapper.orderByAsc(GoodsDO::getState);
                            break;
                        default:
                            log.debug("不支持的排序字段");
                            break;
                    }
                }
            });
        }
    }

    /**
     * 将当前用于查询的DTO中的查询数据转换为 LambdaQuerySqlWrapper
     *
     * @return 条件构造器 LambdaQuerySqlWrapper
     */
    @Override
    public LambdaQueryWrapper<GoodsDO> toWrapper() {
        LambdaQueryWrapper<GoodsDO> wrapper = new LambdaQueryWrapper<>();
        dealWithFilter(wrapper);
        dealWithOrderBy(wrapper);
        return wrapper;
    }

    @SuppressWarnings("WeakerAccess")
    @ApiModel("排序数据DTO")
    @Data
    @EqualsAndHashCode(callSuper = false)
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SortEntity {

        /**
         * 排序方式，顺序
         */
        @ApiModelProperty(hidden = true)
        @JsonIgnore
        public static final String SORT_ASC = "ASC";

        /**
         * 排序方式，倒序
         */
        @ApiModelProperty(hidden = true)
        @JsonIgnore
        public static final String SORT_DESC = "DESC";

        /**
         * 排序字段
         */
        @ApiModelProperty("排序字段")
        private String column;

        /**
         * 排序方式
         */
        @ApiModelProperty("排序方式 ASC DESC")
        private String order;

    }

}
